package com.ruoyi.quality.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.common.Defect;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.quality.domain.QualityClassificationData;
import com.ruoyi.quality.domain.bo.QualityClassificationDataBo;
import com.ruoyi.quality.domain.vo.QualityClassificationDataVo;
import com.ruoyi.quality.domain.vo.QualityClassificationItemsVo;
import com.ruoyi.quality.domain.vo.QualityClassificationUserData;
import com.ruoyi.quality.mapper.QualityClassificationDataMapper;
import com.ruoyi.quality.mapper.QualityClassificationItemsMapper;
import com.ruoyi.quality.service.IQualityClassificationDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 分级得分Service业务层处理
 *
 * @author ruoyi
 * @date 2023-12-06
 */
@RequiredArgsConstructor
@Service
public class QualityClassificationDataServiceImpl implements IQualityClassificationDataService {

    private final QualityClassificationDataMapper baseMapper;

    private final QualityClassificationItemsMapper itemsMapper;

    /**
     * 查询分级得分
     */
    @Override
    public QualityClassificationDataVo queryById(Long id){
        return baseMapper.selectVoById(id);
    }

    /**
     * 查询分级得分
     */
    @Override
    public QualityClassificationDataVo validByBo(QualityClassificationDataBo bo){
        LambdaQueryWrapper<QualityClassificationData> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoOne(lqw);
    }

    /**
     * 根据工号查询总分
     */
    @Override
    public BigDecimal queryTotalByUserId(Long id) {
        QualityClassificationDataBo bo = new QualityClassificationDataBo();
        bo.setUserId(id);
        List<QualityClassificationDataVo> voList = queryList(bo);
        //求和
        return voList.stream().map(QualityClassificationDataVo::getGrade)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
    }

    /**
     * 查询分级得分
     */
    @Override
    public List<QualityClassificationDataVo> queryByIds(Collection<Long> ids){
        return baseMapper.selectVoBatchIds(ids);
    }

    /**
     * 查询分级得分列表
     */
    @Override
    public TableDataInfo<QualityClassificationDataVo> queryPageList(QualityClassificationDataBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<QualityClassificationData> lqw = buildQueryWrapper(bo);
        Page<QualityClassificationDataVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询分级得分列表
     */
    @Override
    public List<QualityClassificationDataVo> queryList(QualityClassificationDataBo bo) {
        LambdaQueryWrapper<QualityClassificationData> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    /**
     * 查询分级得分列表
     */
    @Override
    public List<QualityClassificationUserData> queryUserList(QualityClassificationDataBo bo) {
        List<QualityClassificationUserData> userList = new ArrayList<>();
        List<QualityClassificationDataVo> dataVos = queryList(bo);
        // 分组统计 grade 字段之和
        try {
            Map<Long, BigDecimal> sumByParentId = dataVos.stream()
                    .collect(Collectors.groupingBy(QualityClassificationDataVo::getParentId,
                            Collectors.reducing(BigDecimal.ZERO, QualityClassificationDataVo::getGrade, BigDecimal::add)));
            sumByParentId.forEach((parentId, sum) -> {
                QualityClassificationUserData userData = new QualityClassificationUserData();
                userData.setId(parentId);
                userData.setGrade(sum);
                userData.setMax(BigDecimal.valueOf(100));
                userList.add(userData);
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        try {
            userList.forEach(item -> {
                //获取当前评价项目
                Long id = item.getId();
                QualityClassificationItemsVo itemsVo = itemsMapper.selectVoById(id);
                //获取评价项目总分
                item.setTotal(itemsVo.getScore());

                //获取当前项目平均分
                QualityClassificationDataBo dataBo = new QualityClassificationDataBo();
                bo.setParentId(id);
                bo.setUserId(null);
                List<QualityClassificationDataVo> voList = queryList(bo);

                BigDecimal averageGrade = voList.stream()
                        .map(QualityClassificationDataVo::getGrade)  // 获取所有的grade值
                        .filter(Objects::nonNull)  // 过滤掉为null的grade值
                        .reduce(BigDecimal.ZERO, BigDecimal::add)  // 将所有grade值相加
                        .divide(BigDecimal.valueOf(
                                        voList.stream().map(QualityClassificationDataVo::getUserId).distinct().count()),
                                2, RoundingMode.HALF_UP);  // 除以userId字段不重复的总个数并保留两位小数

                //计算得分率*100
                BigDecimal grade = item.getGrade();
//                BigDecimal total = item.getTotal();
                //分母为得分项平均分
                BigDecimal score = grade.divide(averageGrade, 2, RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
                //赋值给用户得分项
                // 将分数限制在0到100之间
                if (score.compareTo(BigDecimal.valueOf(100)) > 0) {
                    score = BigDecimal.valueOf(100);
                }
                item.setScore(score);
                item.setName(itemsVo.getItemName());
            });
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return userList;
    }

    /**
     * 查询分级得分列表
     */
    @Override
    public List<QualityClassificationUserData> queryProgressList(QualityClassificationDataBo bo) {
        List<QualityClassificationUserData> userDataList = new ArrayList<>();
        QualityClassificationUserData userData1 = extracted(bo,Defect.FLAW_DETECTION1);
        userDataList.add(userData1);
        QualityClassificationUserData userData2 = extracted(bo,Defect.FLAW_DETECTION2);
        userDataList.add(userData2);
        return userDataList;
    }

    private QualityClassificationUserData extracted(QualityClassificationDataBo bo,Long itemsId) {
        QualityClassificationUserData userData = new QualityClassificationUserData();
        bo.setItemsId(itemsId);
        QualityClassificationDataVo dataVos = validByBo(bo);
        QualityClassificationItemsVo itemsVo = itemsMapper.selectVoById(itemsId);
        QualityClassificationItemsVo itemsParentVo = itemsMapper.selectVoById(itemsVo.getParentId());
        userData.setId(itemsId);
        userData.setName(itemsParentVo.getItemName());
        userData.setGrade(dataVos.getGrade());
        userData.setTotal(itemsVo.getScore());
        BigDecimal score = dataVos.getGrade().divide(itemsVo.getScore(),2,RoundingMode.HALF_UP).multiply(BigDecimal.valueOf(100));
        userData.setScore(score);
        return userData;
    }

    private LambdaQueryWrapper<QualityClassificationData> buildQueryWrapper(QualityClassificationDataBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<QualityClassificationData> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getItemsId() != null, QualityClassificationData::getItemsId, bo.getItemsId());
        lqw.eq(bo.getParentId() != null, QualityClassificationData::getParentId, bo.getParentId());
        lqw.eq(bo.getUserId() != null, QualityClassificationData::getUserId, bo.getUserId());
        lqw.eq(bo.getGrade() != null && bo.getGrade().compareTo(BigDecimal.ZERO) != 0, QualityClassificationData::getGrade, bo.getGrade());
        return lqw;
    }

    /**
     * 新增分级得分
     */
    @Override
    public Boolean insertByBo(QualityClassificationDataBo bo) {
        QualityClassificationData add = BeanUtil.toBean(bo, QualityClassificationData.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }

    /**
     * 修改分级得分
     */
    @Override
    public Boolean updateByBo(QualityClassificationDataBo bo) {
        QualityClassificationData update = BeanUtil.toBean(bo, QualityClassificationData.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(QualityClassificationData entity){
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除分级得分
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if(isValid){
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }
}
